/*
 * protocolMaker.cpp
 *
 *  Created on: 2012-9-25
 *      Author: Administrator
 */
#include <string.h>
#include <dirent.h>
#include <libxml/parser.h>

#include "protocolMaker.hpp"
#include "serialize.hpp"
#include "writer.hpp"
#include "stringResource.hpp"


char inputDirPath[]= "./protocol/" ;
char cppDirPath[] = "./export/c++/" ;
char CSharpNotifyDefPath[] = "./export/c#/_Scripts/NetProxy/NetDef.cs" ;
char CSharpProtoDefPath[] = "./export/c#/_Scripts/NetProxy/ProtoDef.cs" ;
char cSharpDirPath[] = "./export/c#/_Scripts/NetProxy/protocol/" ;


char workBuff[1024 * 1024] ;


int serialize( char* filePath ) ;

static ProtocolModule* modules[1024] ;
static int iModule = 0 ;
int main( ) {
	DIR *inputDir ;
	struct dirent* curEnt ;

	/** 生成 C# 的协议目录 */
	mkdir( cSharpDirPath ) ;
	inputDir = opendir( inputDirPath ) ;
	while( (curEnt = readdir( inputDir )) ) {
		if( strlen(curEnt->d_name ) > 4
				&& strcmp( curEnt->d_name + strlen(curEnt->d_name ) - 4 , ".xml" ) == 0 ) {
			printf( TIP_HANDLING"[%s]\n" , curEnt->d_name ) ;
			sprintf( workBuff , "%s%s" , inputDirPath , curEnt->d_name ) ;
			serialize( workBuff ) ;
		}
	}
	writeCsGlobal( modules , iModule ) ;
	for( int i = 0 ; i < iModule ; ++i ) {
		free( modules[i] ) ;
	}
#if defined( __MINGW32__ ) || defined( __MINGW64__ )
	system("pause");
#endif
	return 0 ;
}

int initProtocolModule( ProtocolModule* module ) {
	module->summary[0] = '\0' ;
	module->creator[0] = '\0' ;
	module->modifies.next = NULL ;
	module->lastModify = &module->modifies ;
	module->includes.next = NULL ;
	module->lastInclude = &module->includes ;
	module->types = NULL ;
	module->requesters = NULL ;
	module->responds = NULL ;
	return 0 ;
}

int serialize( char* filePath ) {
	int ret ;
	xmlDoc *xml = NULL ;
	xmlNode *root ;
	xmlNode *curNode ;
	ProtocolModule *module = (ProtocolModule*)malloc( sizeof( ProtocolModule ) ) ;
	char* value ;
	initProtocolModule( module ) ;


	xml = xmlParseFile( filePath ) ;
	if( !xml ) {
		printf( ERROR_PARSE_XML"[%s]\n" , filePath ) ;
		ret = 1 ;		// 解析错误
		goto fail ;
	}
	root = xmlDocGetRootElement( xml ) ;
	if( xmlStrcmp( root->name , "module" ) ) {
		printf( ERROR_NOT_PROTOCOL"[%s]\n" , filePath ) ;
		ret = 2 ;		// 不是协议定义文件
		goto fail ;
	}
	value = xmlGetProp( root , "id" ) ;
	if( value == NULL ) {
		printf( ERROR_NO_MODULE_ID"[%s]\n" , filePath ) ;
		return 2 ;
	}
	module->id = atoi( value ) ;
	value = xmlGetProp( root , "name" ) ;
	if( value == NULL ) {
		printf( ERROR_NO_MODULE_NAME"[%s]\n" , filePath ) ;
		return 3 ;
	}
	strncpy( module->name , value , sizeof( module->name ) ) ;
//	firstToUpperCase( module->name ) ;



	curNode = xmlFirstElementChild( root) ;
	while( curNode ) {
		if( xmlStrcmp( curNode->name , "type" ) == 0 ) {
			makeType( module , curNode ) ;
		} else if( xmlStrcmp( curNode->name , "request" ) == 0 ) {
			makeRequest( module , curNode ) ;
		} else if( xmlStrcmp( curNode->name , "respond" ) == 0 ) {
			makeRespond( module , curNode ) ;
		} else if( xmlStrcmp( curNode->name , "summary" ) == 0 ) {
			strcpy( module->summary , xmlNodeGetContent( curNode ) ) ;
		} else if( xmlStrcmp( curNode->name , "creator" ) == 0 ) {
			const char *time , *name ;
			time = xmlGetProp( curNode , "time" ) ;
			name = xmlGetProp( curNode , "name" ) ;
			if( !time ) time = "" ;
			if( !name ) name = "" ;
			sprintf( module->creator , "%s  %s" , name , time ) ;
		}else if( xmlStrcmp( curNode->name , "modify" ) == 0 ) {
			const char *time , *name , *reason ;
			time = xmlGetProp( curNode , "time" ) ;
			name = xmlGetProp( curNode , "name" ) ;
			reason = xmlGetProp( curNode , "reason" ) ;
			if( !time ) time = "" ;
			if( !name ) name = "" ;
			if( !reason ) name = "" ;

			module->lastModify->next = new ProtocolModify() ;
			module->lastModify = module->lastModify->next ;
			module->lastModify->next = NULL ;
			sprintf( module->lastModify->modify , "%s  %s  %s" , name , time , reason ) ;
		} else if( ( xmlStrcmp( curNode->name , "include" ) ) == 0 ) {
			const char *file ;
			file = xmlGetProp( curNode , "file" ) ;
			if( file ){
				module->lastInclude->next = new ProtocolInclude() ;
				module->lastInclude = module->lastInclude->next ;
				module->lastInclude->next = NULL ;
				strcpy( module->lastInclude->file , file ) ;
			}
		}
		else {
			printf( ERROR_PARSE_XML"[%s]\n" , curNode->name ) ;
		}
		curNode = xmlNextElementSibling( curNode ) ;
	}
	writeModule( module ) ;
	modules[iModule++] = module ;
	ret = 0 ;

	fail:
	if( xml )	xmlFreeDoc( xml ) ;
	return ret ;
}
